/**
 * Licensed under the Apache License Version 2.0.
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */
package net.interknit.knitter.fw;

import java.io.File;
import java.math.BigDecimal;
import java.math.BigInteger;

public class DefaultTypeInstantiator implements TypeInstantiator
{
	@Override
	public <T> T instantiate(java.lang.Class<T> clazz) throws InstantiationException
	{
		try
		{
			T instance = new KnownTypeInstantiator().instantiate(clazz);

			return instance != null ? instance : clazz.newInstance();
		}
		catch(java.lang.Exception e)
		{
			if(e instanceof InstantiationException)
				throw (InstantiationException) e;
			else
				throw new RuntimeException(e);
		}
	}
}

/**
 * Performs default instantiation of some of the known types that cannot be instantiated using the default
 * no-arg constructor.  The default instances created by this class may not be semantically useful, but will
 * ensure that the objects of these types do not remain uninstantiated.
 */
class KnownTypeInstantiator extends DefaultTypeInstantiator
{
	/**
	 * Creates instance of all known types that cannot be instantiated using the default no-arg constructor,
	 * but are typically encountered.  For example, java.io.File is a type that is typically encountered, but
	 * cannot be instantiated using the default no-arg constructor.
	 */
	@Override
	public <T> T instantiate(Class<T> clazz) throws InstantiationException
	{
		try
		{
			Object instance = null;

			if(clazz.equals(File.class)) instance = new File("");
			else if(clazz.equals(BigDecimal.class)) instance = new BigDecimal(0);
			else if(clazz.equals(BigInteger.class)) instance = new BigInteger("0");

			// TODO add more here

			return (T) instance;
		}
		catch(java.lang.Exception e)
		{
			throw new java.lang.RuntimeException(e);
		}
	}
}